package com.app.business.service;

import com.app.business.model.*;
import com.app.system.jpa.JpaBaseDao;
import com.app.system.jpa.PageBean;
import com.app.system.jpa.Wrapper;
import com.app.system.utils.CollectionUtils;
import com.app.system.utils.ParamUtils;
import com.app.system.utils.dataType.BigDecimalUtils;
import com.app.system.utils.dataType.DateUtils;
import com.app.system.utils.dataType.StringUtils;
import com.app.system.utils.exception.Precondition;
import com.app.system.utils.exception.Response;
import com.google.common.collect.Maps;
import org.apache.poi.util.StringUtil;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.*;

/**
 * Created by ddz on 2020/9/1.
 */
@SuppressWarnings(value = "ALL")
@Service
@Transactional
public class HousePersonForPropertyService extends JpaBaseDao<HousePersonForProperty, Integer> {

    @Autowired
    private HouseService houseService;
    @Autowired
    private ActionHistoryService actionHistoryService;

    /**
     * 根据房源Id得到减免人列表
     *
     * @param contractId
     * @return
     */
    public List<HousePersonForProperty> getHousePersonListByHouseId(Integer houseId) {
        //查询语句
        String hql = " from HousePersonForProperty hpp where hpp.house.id = :houseId order by hpp.id";
        Map<String, Object> map = new HashMap<>();
        map.put("houseId", houseId);
        return this.findHql(hql, map);
    }

    /**
     * 分页处理根据房源id获取
     *
     * @return
     */
    public PageBean<HousePersonForProperty> housePersonForPropertyPageBeanByHouseId(Integer houseId) {
        //查询语句
        StringBuffer query = new StringBuffer(" hp from HousePersonForProperty hp inner join fetch hp.house h ");

        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer(" hp.id ");
        Wrapper wrapper = new Wrapper(query, orderBy);
        wrapper.andEq("h.id",houseId);
        wrapper.initSearchParams();
        return this.pageHql(wrapper);
    }

    /**
     * 根据身份证号得到该减免人
     *
     * @param contractId
     * @return
     */
    public List<HousePersonForProperty> getHousePersonListByIdCard(String idCard) {
        //查询语句
        String hql = " from HousePersonForProperty hpp inner join fetch hpp.house h where hpp.idCard = :idCard order by hpp.id";
        Map<String, Object> map = new HashMap<>();
        map.put("idCard", idCard);
        return this.findHql(hql, map);
    }

    /**
     * 产权人身份证号验证查重
     *
     * @param contractId
     * @param zsProjectId
     * @param chooseHouseNum
     * @return
     */
    public String validateIdCard(Integer houseId, String freeArea, String idCard) {
        StringBuffer hql = new StringBuffer(" select * from house_person_for_property where id != :buyHousePersonId and contract_id =:contractId and id_card =:idCard ");
        Map<String, Object> map = Maps.newLinkedHashMap();
        map.put("idCard", idCard);

        List list = this.findSqlObject(hql.toString(), map);
        if (CollectionUtils.isNotEmpty(list)) {
            return "该身份证号已存在";
        }
        return null;

    }


    /**
     * 删除某房源下所有的减免人员数据
     *
     * @param houseId
     */
    public synchronized void deleteHousePersonForPropertyByHouseId(Integer houseId) {
        String sql = "delete from house_person_for_property where house_id = :houseId";
        this.entityManager.createNativeQuery(sql).setParameter("houseId", houseId).executeUpdate();
    }


    /**
     * 征收项目参数配置数据保存
     *
     * @param request
     * @return
     */
    public synchronized Response housePersonForPropertySave(HttpServletRequest request) {
        int houseId = ParamUtils.getInt(request, "houseId", 0);
        House house = this.houseService.findOne(houseId);

        Precondition.checkAjaxArguement(house != null, "1111", "未找到所需要减免房源，保存失败！");
        //保存之前先删除数据
        this.deleteHousePersonForPropertyByHouseId(house.getId());

        String[] nameArray = ParamUtils.getStringParameters(request, "name");    //减免人
        String[] idCardArray = ParamUtils.getStringParameters(request, "idCard");    //减免人身份证号
        String[] relationArray = ParamUtils.getStringParameters(request, "relation");    //产权人关系
        String[] freeAreaArray = ParamUtils.getStringParameters(request, "freeArea");    //减免面积
        String[] startDateArray = ParamUtils.getStringParameters(request, "startDate");    //开始减免时间
        String[] stopDateArray = ParamUtils.getStringParameters(request, "stopDate");    //减免终止时间
        String[] memoArray = ParamUtils.getStringParameters(request, "memo");    //备注
        //必须不为空，且长度一致（必填）
        Precondition.checkAjaxArguement(nameArray != null && idCardArray != null && freeAreaArray != null, "2222", "数据填写不规范！");
        int length = idCardArray.length;
        String name = null, idCard = null, relation = null, freeArea = null, startDate = null, stopDate = null, memo = null;
        BigDecimal allArea;
        List<HousePersonForProperty> housePersonForPropertyList;
        for (int i = 0; i < length; i++) {
            housePersonForPropertyList = null;
            name = null;
            idCard = null;
            relation = null;
            freeArea = null;
            startDate = null;
            stopDate = null;
            memo = null;
            name = nameArray[i];
            idCard = idCardArray[i];
            relation = relationArray[i];
            freeArea = freeAreaArray[i];
            startDate = startDateArray[i];
            stopDate = stopDateArray[i];
            memo = memoArray[i];
            allArea = BigDecimalUtils.stringToBigDecimal(freeArea);

            Precondition.checkAjaxArguement(allArea.compareTo(new BigDecimal("60")) <= 0, "2222", name + idCard + "减免面积已超过60，请核对后填写！");
            housePersonForPropertyList = this.getHousePersonListByIdCard(idCard);
            if (!CollectionUtils.isEmpty(housePersonForPropertyList)) {
                for (HousePersonForProperty housePersonForPropertys : housePersonForPropertyList) {
                    allArea = BigDecimalUtils.getSum(allArea, housePersonForPropertys.getFreeArea());
                }
                Precondition.checkAjaxArguement(allArea.compareTo(new BigDecimal("60")) <= 0, "2222", name + idCard + "减免面积已超出最大可减免，请核对后填写！");
            }

            if (name != null && !name.equals("") && idCard != null && !idCard.equals("") && freeArea != null && !freeArea.equals("")) {
                HousePersonForProperty housePersonForProperty = new HousePersonForProperty();
                housePersonForProperty.setName(name);
                housePersonForProperty.setIdCard(idCard);
                housePersonForProperty.setRelation(relation);
                housePersonForProperty.setFreeArea(BigDecimalUtils.stringToBigDecimal(freeArea));
                housePersonForProperty.setCheckInDate(new Date());
                housePersonForProperty.setStartDate(startDate == null ? new Date() : DateUtils.stringToDateDefault(startDate));
                housePersonForProperty.setStopDate(stopDate == null ? new Date() : DateUtils.stringToDateDefault(stopDate));
                housePersonForProperty.setMemo(memo);
                housePersonForProperty.setHouse(house);

                this.save(housePersonForProperty);
                this.actionHistoryService.saveActionHistoryByContractId(housePersonForProperty.getHouse().getContract().getId(),
                        "设置房号为" + housePersonForProperty.getHouse().getHouseNumStr() + "的减免人ID为：" + housePersonForProperty.getName(), "设置物业减免人");

            }

        }
        return new Response("0001", "保存成功!");
    }


    /**
     * 得到房源id和当前房源的List<HousePersonForProperty>对应的map
     *
     * @param buyHousePersonList
     * @return
     */
    public Map<String, List<Map>> getHousePersonForPropertyByHouse() {
        List<Map> valueList = null;
        StringBuffer sql = new StringBuffer(" SELECT * FROM house_person_for_property bbp, ");
        sql.append(" (SELECT h.id AS houseId FROM house h) ha ");
        sql.append(" WHERE bbp.house_id=ha.houseId");
        Query query = this.entityManager.createNativeQuery(sql.toString());
        List<Map> housePersonForPropertyList = query.unwrap(org.hibernate.SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
        Map<String, List<Map>> map = Maps.newLinkedHashMap();
        if (CollectionUtils.isNotEmpty(housePersonForPropertyList)) {
            for (Map map1 : housePersonForPropertyList) {
                String houseId = String.valueOf(map1.get("houseId"));
                valueList = map.get(houseId) == null ? new ArrayList<>() : map.get(houseId);
                valueList.add(map1);
                map.put(houseId, valueList);
            }
        }
        return map;
    }


    /**
     * 根据房源id得到减免人列表MAp
     *
     * @param houseId
     * @return
     */
    public Map<String, String> getHousePersonForPropertyListByHouseId() {

        StringBuffer sql = new StringBuffer(" SELECT hp.house_id AS 'houseId',GROUP_CONCAT(hp.name) AS 'nameStr' ");
        sql.append("  FROM house_person_for_property hp ");
        sql.append("  GROUP BY hp.house_id");
        List<Map> housePersonForPropertyNameStrList = this.findSql(sql.toString(), null);

        Map<String, String> resultMap = Maps.newLinkedHashMap();

        if (CollectionUtils.isNotEmpty(housePersonForPropertyNameStrList)) {
            for (Map  map1 : housePersonForPropertyNameStrList) {
                String houseId = map1.get("houseId").toString();
                String HousePersonForPropertyName = map1.get("nameStr").toString();
                resultMap.put(houseId, HousePersonForPropertyName);
            }
        }
        return resultMap;
    }

    /**
     * 安置项目对应房源楼栋信息
     * @return
     */
    public Map<String,List<String>> getHouseBuildNumByAzId() {
        StringBuffer sql = new StringBuffer(" SELECT h.az_project_id as 'azProjectId',h.build_num as 'buildNum' ");
        sql.append(" FROM  house h ");
        sql.append(" GROUP BY h.az_project_id,h.build_num ");
        List<Map> housePersonForPropertyNameStrList = this.findSql(sql.toString(), null);

        Map<String, List<String>> resultMap = Maps.newLinkedHashMap();

        if (CollectionUtils.isNotEmpty(housePersonForPropertyNameStrList)) {
            for (Map  map1 : housePersonForPropertyNameStrList) {
                List<String> buildNumList = new LinkedList<>();
                String azProjectId = map1.get("azProjectId").toString();
                String buildNum = map1.get("buildNum").toString();
                if (resultMap != null) {
                    if (CollectionUtils.isNotEmpty(resultMap.get(azProjectId))) {
                        buildNumList = resultMap.get(azProjectId);
                    }
                }
                buildNumList.add(buildNum);
                resultMap.put(azProjectId,buildNumList);
            }
        }
        return resultMap;
    }

    public Map<String,List<String>> getHouseBuildNumByAzId(String zsProjectId) {
        StringBuffer sql = new StringBuffer(" SELECT h.az_project_id as 'azProjectId',h.build_num as 'buildNum' ");
        sql.append(" FROM  house h ");
        sql.append("where h.id in (select zph.house_id from zs_project_house zph where zph.zs_project_id in (" + zsProjectId + ")) ");

        sql.append(" GROUP BY h.az_project_id,h.build_num ");
        List<Map> housePersonForPropertyNameStrList = this.findSql(sql.toString(), null);

        Map<String, List<String>> resultMap = Maps.newLinkedHashMap();

        if (CollectionUtils.isNotEmpty(housePersonForPropertyNameStrList)) {
            for (Map  map1 : housePersonForPropertyNameStrList) {
                List<String> buildNumList = new LinkedList<>();
                String azProjectId = map1.get("azProjectId").toString();
                String buildNum = map1.get("buildNum").toString();
                if (resultMap != null) {
                    if (CollectionUtils.isNotEmpty(resultMap.get(azProjectId))) {
                        buildNumList = resultMap.get(azProjectId);
                    }
                }
                buildNumList.add(buildNum);
                resultMap.put(azProjectId,buildNumList);
            }
        }
        return resultMap;
    }

    /**
     * 通过项目Id 楼栋号 获取该楼栋的最高层次
     * @return
     */
    public Map<String,Map<String,Integer>> getMaxFoolrByAzIdBuildNum() {
        StringBuffer sql = new StringBuffer(" SELECT  h.az_project_id AS 'azProjectId',h.build_num AS 'buildNum',MAX(h.floor) AS 'maxFloor' ");
        sql.append(" FROM  house h ");
        sql.append(" GROUP BY h.az_project_id,h.build_num ");
        List<Map> housePersonForPropertyNameStrList = this.findSql(sql.toString(), null);

        Map<String,Map<String,Integer>> resultMap = Maps.newLinkedHashMap();

        if (CollectionUtils.isNotEmpty(housePersonForPropertyNameStrList)) {
            for (Map  map1 : housePersonForPropertyNameStrList) {
                Map<String,Integer> item = new HashMap<>();
                String azProjectId = map1.get("azProjectId").toString();
                String buildNum = map1.get("buildNum").toString();
                Integer maxFloor = Integer.valueOf(map1.get("maxFloor").toString());
                item.put(buildNum,maxFloor);
                resultMap.put(azProjectId,item);
            }
        }
        return resultMap;
    }

}
